package com.example.mysql_mybatis_demo.springsource.config;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.SmartFactoryBean;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 自定义的 FactoryBean
 * 注意 FactoryBean需要声明为Bean，加入到Spring容器中
 * 更改实现FactoryBean，改为实现SmartFactoryBean，这样可以修改是否懒加载
 */
@Component
public class FactoryBeanFivTest implements SmartFactoryBean {
    /**
     * getObject() 是 FactoryBean的核心方法，如果直接调用这个方法就是执行创建 Bean的流程。
     * 反正最终返回创建的Bean即可，因此在这里可以做很多复杂的工作
     *
     * @return
     * @throws Exception
     */
    @Override
    public Object getObject() throws Exception {
        String uuid = UUID.randomUUID().toString().substring(0, 5);
        System.out.println("调用NonBeanTest的5号Factory，关闭懒加载，在启动时创建内部Bean实例，设置其名称为 NonBean_Fiv_" + uuid);
        // 注意调用 Factory时，每次都会new一个新的类实例，但是到底是不是新的new呢？这就得看下面的isSingleton是单例还是共享了
        NonBeanTest nonBeanTest = new NonBeanTest();
        // 每次调用Factory实例化Bean时，给Bean赋一个随机值，用来验证是否单例
        nonBeanTest.setName("NonBean_Fiv_" + uuid);
        return nonBeanTest;
    }

    @Override
    public Class<?> getObjectType() {
        return NonBeanTest.class;
    }

    /**
     * 规定为单例模式
     *
     * @return
     */
    @Override
    public boolean isSingleton() {
        return true;
    }

    /**
     * 返回True，关闭懒加载。
     * 返回False，开启懒加载，只有显式调用 FactoryBeanFivTest.getObject() 时才会实例化Bean
     *
     * @return
     */
    @Override
    public boolean isEagerInit() {
        return true;
    }
}
